home *** CD-ROM | disk | FTP | other *** search
/ Ray Dream Studio 5 / Ray Dream.iso / pc / DreamSDK / Windows / SAMPLES / CAMERA / CAMS / COMCAMS.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-11  |  11.2 KB  |  331 lines

  1. /* $Id: COMCamS.cpp 1.6 1997/04/11 03:38:36 damien Exp $ */
  2.  
  3. ////////////////////////////////////////////////////////////////////////
  4. //   First Camera Example : Spherical Camera                          //
  5. //--------------------------------------------------------------------//
  6. //   Implementation of the Spherical Camera Interface                                 //
  7. //////////////////////////////////////////////////////////////////////// 
  8.  
  9. // Copyright (c) 1995, Ray Dream, Inc. All rights reserved.
  10.  
  11. #include "math.h"
  12.  
  13. #ifndef __COMCAMS__
  14. #include "COMCAMS.h"
  15. #endif
  16.  
  17. #ifndef __CAMSDLL__
  18. #include "CAMSDLL.h"
  19. #endif
  20.  
  21. #ifndef __3DCOFAIL__
  22. #include "3DCoFail.h"
  23. #endif
  24.          
  25. // Global value for Unit Conversion and Angle limits
  26. NUM3D InternalZoom = 10000.0;        
  27. NUM3D kQuick180    = 180.0; //3.1415926535897932384626233; // 180 deg.
  28. NUM3D kRadToDeg    = 180.0/3.1415926535897932384626233;
  29. NUM3D kQuick288    = 288.0;
  30.  
  31.  
  32.          
  33. // Tool to get the Global Coordinates from the Local Coordinates 
  34. void LocalToGlobal(TRANSFORM3D* transform,VECTOR3D* LocalPos,VECTOR3D* GlobalPos) {
  35.   // Axes rotations
  36.   (*GlobalPos)[0]=transform->fR.fix*(*LocalPos)[0]
  37.                   +transform->fR.fjx*(*LocalPos)[1]
  38.                   +transform->fR.fkx*(*LocalPos)[2];
  39.   (*GlobalPos)[1]=transform->fR.fiy*(*LocalPos)[0]
  40.                   +transform->fR.fjy*(*LocalPos)[1]
  41.                   +transform->fR.fky*(*LocalPos)[2];
  42.   (*GlobalPos)[2]=transform->fR.fiz*(*LocalPos)[0]
  43.                   +transform->fR.fjz*(*LocalPos)[1]
  44.                   +transform->fR.fkz*(*LocalPos)[2];
  45.   // Unit conversion : Points Units to 3D Units 
  46.   (*GlobalPos)[0] /= 288.0;  
  47.   (*GlobalPos)[1] /= 288.0;  
  48.   (*GlobalPos)[2] /= 288.0;  
  49.   // Origin translation
  50.   (*GlobalPos)[0] += transform->fT[0];
  51.   (*GlobalPos)[1] += transform->fT[1];
  52.   (*GlobalPos)[2] += transform->fT[2];
  53.   }
  54.  
  55. // Tool to get the Global Coordinates from the Local Coordinates for a Vector
  56. void LocalToGlobalVector(TRANSFORM3D* transform,VECTOR3D* LocalPos,VECTOR3D* GlobalPos) {
  57.   // Axes rotations
  58.   (*GlobalPos)[0]=transform->fR.fix*(*LocalPos)[0]
  59.                   +transform->fR.fjx*(*LocalPos)[1]
  60.                   +transform->fR.fkx*(*LocalPos)[2];
  61.   (*GlobalPos)[1]=transform->fR.fiy*(*LocalPos)[0]
  62.                   +transform->fR.fjy*(*LocalPos)[1]
  63.                   +transform->fR.fky*(*LocalPos)[2];
  64.   (*GlobalPos)[2]=transform->fR.fiz*(*LocalPos)[0]
  65.                   +transform->fR.fjz*(*LocalPos)[1]
  66.                   +transform->fR.fkz*(*LocalPos)[2];
  67.   // Unit conversion : Points Units to 3D Units 
  68.   (*GlobalPos)[0] /= 288.0;
  69.   (*GlobalPos)[1] /= 288.0;
  70.   (*GlobalPos)[2] /= 288.0;
  71.   }
  72.  
  73. // Tool to get the Local Coordinates from the Global Coordinates             
  74. void GlobalToLocal(TRANSFORM3D* transform,VECTOR3D* GlobalPos,VECTOR3D* LocalPos) {
  75.   // Origin translation
  76.   (*GlobalPos)[0] -= transform->fT[0];
  77.   (*GlobalPos)[1] -= transform->fT[1];
  78.   (*GlobalPos)[2] -= transform->fT[2];
  79.    // Unit conversion : 3D Units to Points Units
  80.   (*GlobalPos)[0] *= 288.0;
  81.   (*GlobalPos)[1] *= 288.0;
  82.   (*GlobalPos)[2] *= 288.0;
  83.  
  84.   // Axes rotations
  85.   (*LocalPos)[0]=transform->fR.fix*(*GlobalPos)[0]
  86.                   +transform->fR.fiy*(*GlobalPos)[1]
  87.                   +transform->fR.fiz*(*GlobalPos)[2];
  88.   (*LocalPos)[1]=transform->fR.fjx*(*GlobalPos)[0]
  89.                   +transform->fR.fjy*(*GlobalPos)[1]
  90.                   +transform->fR.fjz*(*GlobalPos)[2];
  91.   (*LocalPos)[2]=transform->fR.fkx*(*GlobalPos)[0]
  92.                   +transform->fR.fky*(*GlobalPos)[1]
  93.                   +transform->fR.fkz*(*GlobalPos)[2];
  94.   }
  95.  
  96. // Tool to get the Local Coordinates from the Global Coordinates for a Vector
  97. void GlobalToLocalVector(TRANSFORM3D* transform,VECTOR3D* GlobalPos,VECTOR3D* LocalPos) {
  98.    // Unit conversion : 3D Units to Points Units
  99.   (*GlobalPos)[0] *= 288.0;
  100.   (*GlobalPos)[1] *= 288.0;
  101.   (*GlobalPos)[2] *= 288.0;
  102.  
  103.   // Axes rotations
  104.   (*LocalPos)[0]=transform->fR.fix*(*GlobalPos)[0]
  105.                   +transform->fR.fiy*(*GlobalPos)[1]
  106.                   +transform->fR.fiz*(*GlobalPos)[2];
  107.   (*LocalPos)[1]=transform->fR.fjx*(*GlobalPos)[0]
  108.                   +transform->fR.fjy*(*GlobalPos)[1]
  109.                   +transform->fR.fjz*(*GlobalPos)[2];
  110.   (*LocalPos)[2]=transform->fR.fkx*(*GlobalPos)[0]
  111.                   +transform->fR.fky*(*GlobalPos)[1]
  112.                   +transform->fR.fkz*(*GlobalPos)[2];
  113.   }
  114.  
  115.  
  116.  
  117.  
  118.  
  119. #undef INTERFACE
  120. #define INTERFACE SphereCamera
  121. // Constructor / Destructor of the C++ Object :
  122. SphereCamera::SphereCamera() {
  123.   fCRef=0; // Reference Counter
  124.   // Rotation matrix initialized to identity :
  125.   fTransform.fR.fix=fTransform.fR.fjy=fTransform.fR.fkz=1.0;
  126.   fTransform.fR.fjx=fTransform.fR.fkx=0.0;
  127.   fTransform.fR.fiy=fTransform.fR.fky=0.0;
  128.   fTransform.fR.fiz=fTransform.fR.fjz=0.0;
  129.   // Translation vector initialized to zero :
  130.   fTransform.fT[0]=fTransform.fT[1]=fTransform.fT[2]=0.0;
  131.   // Data initialisation :
  132.   fData.fZoomCoef=10;    // 10xZoom Factor
  133.   fData.fAngle   =360;   // Visible space in degree
  134.   QuickAngle=((NUM3D)fData.fAngle)/2; // Half Angle : the limits are -QuickAngle to +QuickAngle
  135.   QuickZoom =fData.fZoomCoef; // NUM3D Value of Zoom for calculation
  136.   Coef=QuickZoom*kQuick288/InternalZoom*kQuick180/QuickAngle;       // Unit conversion factor
  137.   }
  138.   
  139. SphereCamera::~SphereCamera() {
  140.   global_count_Obj--; 
  141.   }
  142.   
  143. // IUnknown Interface :
  144. HRESULT SphereCamera::QueryInterface(THIS_ REFIID riid,LPVOID FAR* ppvObj) {
  145.   *ppvObj=NULL;
  146.   
  147.   // The SphereCamera knows the interfaces of the parent Objects
  148.   if (IsEqualIID(riid, IID_IUnknown))
  149.     *ppvObj=(LPVOID)this;
  150.   else if (IsEqualIID(riid, IID_I3DExCamera))
  151.     *ppvObj=(LPVOID)this;
  152.   else if (IsEqualIID(riid, IID_I3DExDataExchanger))
  153.     *ppvObj=(LPVOID)this;
  154.   else if (IsEqualIID(riid, IID_I3DExtension))
  155.     *ppvObj=(LPVOID)this;
  156.     
  157.   // we must add reference if we return an interface
  158.   if (*ppvObj!=NULL) {
  159.     ((LPUNKNOWN)*ppvObj)->AddRef();
  160.     return NOERROR;
  161.     }
  162.   else {
  163.     return ResultFromScode(E_NOINTERFACE);
  164.     }
  165.   }
  166.  
  167. ULONG SphereCamera::AddRef(THIS) {
  168.   return fCRef++;
  169.   }
  170.   
  171. ULONG SphereCamera::Release(THIS) {
  172.   ULONG UnreleaseObject=fCRef--;
  173.   
  174.   if (fCRef==0)
  175.      delete this; // No reference left, so destroy the object
  176.   
  177.   return UnreleaseObject;
  178.   // local variable used, because fCRef can be destroyed before.
  179.   }
  180.   
  181. // I3DExtension methods :
  182. I3DExtension* SphereCamera::Clone(THIS) {
  183.     SphereCamera* theClone = new SphereCamera;
  184.     if (theClone) {
  185.     theClone->AddRef();
  186.       theClone->fTransform=fTransform; // Copy Data and internal coefficient.
  187.       theClone->fData     =fData;
  188.       theClone->QuickAngle=QuickAngle;
  189.       theClone->QuickZoom =QuickZoom;
  190.       theClone->Coef      =Coef;
  191.       }                               
  192.     return theClone;
  193.   }   
  194.  
  195. HRESULT SphereCamera::ShellUtilitiesInit(THIS_ IShUtilities* shellUtilities) {
  196.     InitCoFailure(shellUtilities);
  197.     return NOERROR;
  198.     }
  199.  
  200. // I3DExDataExchanger methods :
  201. ExtensionDataMap* SphereCamera::GetExtensionDataMap(THIS) {
  202.     return NULL;
  203.   }               
  204.   
  205. void* SphereCamera::GetExtensionDataBuffer(THIS) {
  206.   return &fData; // used by the shell to set the new parameters
  207.   }
  208.   
  209. HRESULT SphereCamera::ExtensionDataChanged(THIS) {
  210.   QuickZoom=fData.fZoomCoef;
  211.   QuickAngle=((NUM3D)fData.fAngle)/2; // The Shell considers the total angle
  212.                                                                                            // but the Camera goes from -QuickAngle to +QuickAngle    
  213.   Coef=QuickZoom*kQuick288/InternalZoom*kQuick180/QuickAngle;
  214.   // recalculate the different factors.
  215.   return NOERROR;
  216.   }
  217.  
  218. HRESULT SphereCamera::HandleEvent(THIS_ ULONG SourceID) {
  219.   return ResultFromScode(E_NOTIMPL);
  220.   }
  221.  
  222. short SphereCamera::GetResID(THIS) {
  223.   return 130; // this is the view ID in the resource file.
  224.   }
  225.   
  226. // I3DExCamera methods :
  227. HRESULT SphereCamera::SetTransform(THIS_ TRANSFORM3D* transform) {
  228.     fTransform=*transform; // Copy the data of transform and not the pointer.
  229.     return NOERROR;
  230.     }
  231.  
  232. // Ray Creation :
  233. BOOLEAN SphereCamera::CreateRay(THIS_ VECTOR2D* screenPosition, VECTOR3D* resultOrigin, VECTOR3D* resultDirection) {
  234.   VECTOR3D SpherePos;
  235.   NUM3D    theta,phi,sintheta,costheta,sinphi,cosphi;
  236.  
  237.   SpherePos[0]=SpherePos[1]=SpherePos[2]=0.0;
  238.   LocalToGlobal(&fTransform,&SpherePos,resultOrigin);
  239.   // Origin of the Ray is the center of the Sphere.
  240.   
  241.   theta=(*screenPosition)[0]/Coef;
  242.   phi  =(*screenPosition)[1]/Coef;
  243.   
  244.   
  245.   sintheta=sin(theta / kRadToDeg);
  246.     costheta=cos(theta / kRadToDeg); //QuickSinCos(theta,sintheta,costheta);
  247.   sinphi=sin(phi / kRadToDeg);
  248.     cosphi=cos(phi / kRadToDeg); //QuickSinCos(phi,sinphi,cosphi);
  249.   
  250.   SpherePos[0]=sintheta*cosphi;
  251.   SpherePos[1]=sinphi;
  252.   SpherePos[2]=-costheta*cosphi;
  253.   // 3D Coordinates (x,y,z) from Spherical coordinates  (r=1,theta,phi)
  254.   
  255.   LocalToGlobalVector(&fTransform,&SpherePos,resultDirection);
  256.     NUM3D norm=sqrt(SQR((*resultDirection)[0]) + SQR((*resultDirection)[1]) + SQR((*resultDirection)[2]));
  257.     (*resultDirection)[0] /= norm;
  258.     (*resultDirection)[1] /= norm;
  259.     (*resultDirection)[2] /= norm;
  260.   //resultDirection->Normalize(*resultDirection);
  261.   // Direction vector must be in Global Coordinates System and Normalized
  262.   
  263.   // Angle selection :
  264.   if (theta>QuickAngle || theta<-QuickAngle) {
  265.     return FALSE; // Not in front of the camera
  266.     }
  267.   if (phi>QuickAngle/2 || phi<-QuickAngle/2) {
  268.     return FALSE; // Not in front of the camera
  269.     }
  270.   
  271.   return TRUE;
  272.   }
  273.   
  274.   
  275. // 3D Projection :
  276. BOOLEAN SphereCamera::Project3DTo2D(THIS_ VECTOR3D* position, VECTOR2D* resultScreenPosition, NUM3D* resultDistanceToScreen) {
  277.   VECTOR3D tempV;
  278.   NUM3D    theta,phi,x2,z2,r,norm;
  279.  
  280.     norm=sqrt(SQR((*position)[0]) + SQR((*position)[1]) + SQR((*position)[2]));
  281.     tempV[0]=(*position)[0]/norm;
  282.     tempV[1]=(*position)[1]/norm;
  283.     tempV[2]=(*position)[2]/norm;
  284.   //position->Normalize(tempV);
  285.   
  286.   // Get the Spherical coordinates : ro,theta,phi
  287.   x2=tempV[0]*tempV[0];
  288.   z2=tempV[2]*tempV[2];
  289.   r=x2+z2;
  290.   r=sqrt(r); // Must be calculate to get phi               
  291.   
  292.   theta=atan2(tempV[0], -tempV[2]) * kRadToDeg; //QuickArcSinCos(tempV[0],-tempV[2],theta);
  293.   phi=atan2(tempV[1], r) * kRadToDeg; //QuickArcSinCos(tempV[1],r,phi);
  294.   
  295.   if (theta>kQuick180) {
  296.     theta-=kQuick180*2; // theta : -180∞ to 180∞ (theta - 360)
  297.     }                    
  298.   if (phi>kQuick180) {
  299.     phi-=kQuick180*2;   // phi   : -90∞  to 90∞ 
  300.     }
  301.  
  302.   (*resultScreenPosition)[0]=theta*Coef;
  303.   (*resultScreenPosition)[1]=phi*Coef;
  304.   *resultDistanceToScreen=sqrt(SQR((*position)[0]) + SQR((*position)[1]) + SQR((*position)[2]));
  305.   //*resultDistanceToScreen=position->GetNorm();
  306.   
  307.   // Angle selection :
  308.   /*if ((theta>QuickAngle)||(theta<-QuickAngle)) {
  309.     return FALSE;
  310.     }
  311.   if ((phi>(QuickAngle>>1))||(phi<-(QuickAngle>>1))) {
  312.     return FALSE;
  313.     }*/
  314.  
  315.   return TRUE;
  316.   }                                           
  317.   
  318. ULONG SphereCamera::GetPrimitiveID(THIS)    {
  319.     return 0;
  320.     }
  321.   
  322. ULONG SphereCamera::Clip3D(THIS_ FACET3D* localFacet, VERTEX3D* localVertices,
  323.                                                                       FACET3D* cameraFacet, VERTEX3D* cameraVertices,
  324.                                                                           NUM3D* clipBox) {
  325.     return 0;        /*** to do ***/
  326.     }
  327.  
  328. BOOLEAN SphereCamera::ClipLine3D(THIS_ VECTOR3D* P1, VECTOR3D* P2) {
  329.     return FALSE;            /*** to do ***/
  330.     }
  331.